package br.com.affero.testewel.action;

import org.apache.struts.actions.DispatchAction;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;

import br.com.affero.testewel.exception.ModelValidationException;
import br.com.affero.testewel.form.DocumentForm;
import br.com.affero.testewel.model.document.Document;
import br.com.affero.testewel.model.document.DocumentService;
import br.com.affero.testewel.model.user.UserService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * Controller do módulo de documentos.
 * Todas as ações de CRUD de Document estão concentradas aqui.
 * 
 * @author Welington Veiga
 * @since 21/12/2011
 * 
 */
public class DocumentsAction  extends DispatchAction {

	 private static final String DOCUMENTS = "documents"; 
	 private static final String DOCUMENT  = "document"; 
	 private static final String IS_UPDATE    = "isupdate";
	 
	 
	 private static final String SUCCESS_VIEW = "success";
	 private static final String FAILURE_VIEW = "failure";
	
	 /**
	  * Ação para obtenção de todos os Document cadastrado no sistema.
	  */
	 public ActionForward list(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) 
			 throws Exception {
	
		 request.setAttribute(DOCUMENTS, DocumentService.getInstance().getAll());
		 return mapping.findForward(SUCCESS_VIEW);
     }
	 
	 /**
	  * Ação para inserir/atualizar os dados de um Document.
	  * Observe que tanto adicionar, quanto atualizar significa colocar o Document está em edição. 
	  */
	 public ActionForward edit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
			 throws Exception {
        
		DocumentForm documentForm = (DocumentForm) form;
		Document document;
		
		// Verificando se é uma inserção ou uma atualização.
		/** @todo tratar quando o id existir mas o document não for obtido.*/
		final String id = documentForm.getId();
		if(isUpdate(id)){
			document = DocumentService.getInstance().findById(Long.parseLong(id));
		}else
			document = new Document();
		
		documentToForm(document, documentForm);
		return mapping.findForward(SUCCESS_VIEW);
     } 
	 
	 /**
	  * Ação para salvar um Document.
	  * Após sua criação ou alteração.
	  */
	 public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) 
			 	throws Exception {
	        
	 	 DocumentForm documentForm = (DocumentForm) form;
	 	 String filePath = getServlet().getServletContext().getRealPath("/") +"upload";
	 	 FormFile file   = documentForm.getFile();
	 	 String   destination = getServlet().getServletContext().getRealPath("/") +"upload";
	 	 try{
	 		 Document document = documentFromForm(documentForm);
	 		 DocumentService.getInstance().save(document, file, destination );
	 		request.setAttribute(DOCUMENT, document);	
	 		return mapping.findForward(SUCCESS_VIEW);
	 	 }catch(ModelValidationException valE){
	 		return mapping.findForward(FAILURE_VIEW);
	 	 }
     }

	 /**
	  * Ação para exibição de detalhes de um documento.
	  */
	 public ActionForward detail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) 
			 	throws Exception {
		 final DocumentForm docForm = (DocumentForm) form;
		 final Document document =  DocumentService.getInstance().findById(Long.parseLong(docForm.getId()));
		 request.setAttribute(DOCUMENT, document);	 
		 return mapping.findForward(SUCCESS_VIEW);
	 }
	 
	 /**
	  * Ação para exclusão de um documento.
	  */
	 public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) 
			 	throws Exception {
		 DocumentService.getInstance().delete(Long.parseLong(request.getParameter("id")));
		 return mapping.findForward(SUCCESS_VIEW);
	 }	 
	 
	 /**
	  * Método que verifica se um dado identificador é de inserção ou atualização, sob os seguintes critérios:
	  * 
	  * <ul>
	  * 	<li>O id não pode ser nulo</li>
	  * 	<li>O id não pode ter tamanho zero</li>
	  * 	<li>O id não pode ser zero</li>
	  * </ul>
	  * 
	  * @param id identificador desejado.
	  */
	 private Boolean isUpdate(String id){
		 return id != null && id.trim().length() != 0 && Long.parseLong(id) != 0L;
	 }
	 
	 /**
	  * Método que a partir do Form contrói um Document.
	  * OBS: Dentro da camada de negócio, o próprio serviço autentica os dados e popula os dados não disponibilizados pelo form.
	  * 
	  * @param form formulário com os dados recebidos.
	  * @return Document populado com os dados disponíveis no Form
	  */
	 private Document documentFromForm(DocumentForm form){
		 
		 Document document;
		 if(isUpdate(form.getId()))
			 document = DocumentService.getInstance().findById(Long.parseLong(form.getId()));
		 else
			 document =  new Document();
		 document.setTitle(form.getTitle());
		 document.setDescription(form.getDescription());
		 document.setUser(UserService.getInstance().getCurrUser());
		 return document;
	 }
	 
	 /**
	  * Método que copia o Documen para um form, para sua exibição na tela de edição.
	  *  
	  * @param document
	  * @param form
	  * @return
	  */
	 private DocumentForm documentToForm(Document  document, DocumentForm form){
		 if(document.getId() != null)
			 form.setId(document.getId().toString());
		 form.setDescription(document.getDescription());
		 form.setTitle(document.getTitle());
		 return form;
	 }
			 
			 
}